// surface view 
package com.liquidcode.cellular;

import entities.CPlayer;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.opengl.GLSurfaceView;
import android.text.method.Touch;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;

public class GLSurface extends GLSurfaceView implements SensorEventListener {
	private GLRenderer mRenderer = null;
	private boolean m_TouchingStick = false;
	private SensorManager mSensorManager = null; 
	private Sensor mAccelerometer = null;
	private float mLastAccelX = 0.0f;
	private float mLastAccelY = 0.0f;
	private float MOVEMENT_THRESHOLD = 0.2f;
	private float MAX_MOVEMENT_THRESHOLD = 2.0f;
	private float CONSTANTLY_MOVE_THRESHOLD = 1.2f;
	private boolean mAccelInitialized = false;

	public GLSurface(Context context) {
		super(context);
		mRenderer = new GLRenderer();
		mRenderer.context = context;
		setRenderer(mRenderer);
		 // register for the accelerometer events 
        mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
        mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
        mAccelInitialized = false; 
	}

	public GLSurface(Context context, AttributeSet attrs) {
		super(context, attrs);
		mRenderer = new GLRenderer();
		mRenderer.context = context;
		setRenderer(mRenderer);
		 mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
	     mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
	     mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
	     mAccelInitialized = false;
	}
	
	// accelerometer event 
	public void onSensorChanged(SensorEvent ev)
	{
		if( GameInfo.getInstance().IsPaused ) { 
			return;
		}
		
		float xAccel = ev.values[0];
		float yAccel = ev.values[1];
		
		if( mAccelInitialized )
		{			
			if( xAccel > MAX_MOVEMENT_THRESHOLD ) {
				xAccel = MAX_MOVEMENT_THRESHOLD;
			}
			if( xAccel < -MAX_MOVEMENT_THRESHOLD ) {
				xAccel = -MAX_MOVEMENT_THRESHOLD;
			}
			if( yAccel > MAX_MOVEMENT_THRESHOLD ) {
				yAccel = MAX_MOVEMENT_THRESHOLD;
			}
			if( yAccel < -MAX_MOVEMENT_THRESHOLD ) {
				yAccel = -MAX_MOVEMENT_THRESHOLD;
			}
			
			CTrailManager.getInstance().StartSpawn = true;
			float deltaX = Math.abs(mLastAccelX - xAccel);
			float deltaY = Math.abs(mLastAccelY - yAccel);
			// even though we want to make sure the change is greater than the threshold to start moving 
			// we also dont want the user to have to constantly be moving the accelerometer for it to register
			// so the second if check ensures that the current acceleration reading is above a "constantly move" threshold
			if( deltaX < MOVEMENT_THRESHOLD && deltaY < MOVEMENT_THRESHOLD ) 
			{
				if( Math.abs(xAccel) < CONSTANTLY_MOVE_THRESHOLD && Math.abs(yAccel) < CONSTANTLY_MOVE_THRESHOLD )
				{
					CTrailManager.getInstance().StartSpawn = false;
					CPlayer.getInstance().DisablePlayerMovement();
				}
				return;
			}
			
			CPlayer.getInstance().EnablePlayerMovement();
			CInputManager.getInstance().HandleAccelerometerMovement(xAccel, yAccel);
//			if( Math.abs(mLastAccelX - xAccel) > MOVEMENT_THRESHOLD || Math.abs(mLastAccelY - yAccel) > MOVEMENT_THRESHOLD)
//			{	
//				CInputManager.getInstance().HandleAccelerometerMovement(xAccel, yAccel);
//			}
//			else
//			{
//				//CPlayer.getInstance().DisablePlayerMovement();
//			}
			
			mLastAccelX = xAccel;
			mLastAccelY = yAccel;
		}
		else
		{
			CPlayer.getInstance().DisablePlayerMovement();
			mLastAccelX = xAccel; 
			mLastAccelY = yAccel;
			mAccelInitialized = true;
		}
	}
	
	public void onAccuracyChanged(Sensor sensor, int accuracy) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public boolean onTouchEvent(MotionEvent ev) {

		int action = ev.getAction() & MotionEvent.ACTION_MASK;
		
		if( GameInfo.getInstance().IsPaused ) { 
			return false;
		}
		
		switch(action)
		{			
			case MotionEvent.ACTION_DOWN:
			{
				CInputManager.getInstance().setLatestTouch(ev.getX(), ev.getY());
				if( CAttackManager.getInstance().CurrentAttackType == CAttackManager.TRIGGER_SHOT && CAttackManager.getInstance().getTriggerShot().hasShellFired() == true) {
					//CAttackManager.getInstance().getTriggerShot().ActivateTrigger(owner, fromX, fromY, toX, toY, needsTarget)
					CBulletManager.getInstance().ActivateShell(ev.getX(), ev.getY());
				}
				else {
					CAttackManager.getInstance().CreateAttack(CAttackManager.getInstance().CurrentAttackType, CPlayer.getInstance(), CPlayer.getInstance().getPosX(), CPlayer.getInstance().getPosY(), ev.getX(), ev.getY());					
				}
				return true;
			}
		}
				
		return false;
	}

	// accessors
	public GLRenderer getRenderer() {
		return mRenderer;
	}

}